---------------------------------------------------------------------------------- 
-- Engineer: David McNamara
-- 
-- Module Name:    adc_block - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: adc_block uses the pmod-ad1 to sample analog data
----------------------------------------------------------------------------------

library IEEE;                           --ieee library
use IEEE.STD_LOGIC_1164.all;            --std_logic library
use IEEE.NUMERIC_STD.all;               --numeric library


entity adc_block is
  port (
    clk50        : in  std_logic;
    data1        : in  std_logic;
    sclk         : out std_logic;
    cs           : out std_logic;
    rst          : in  std_logic;
    get_samples  : in  std_logic;
    sample_ready : out std_logic                     := '0';
    sample       : out std_logic_vector(15 downto 0) := x"FFFF";
    sampleClk    : out std_logic
    );

end adc_block;

architecture Behavioral of adc_block is

  --state variables
  type   states is (idle, collect, send);
  signal current_state, next_state : states := idle;

  --signal tmp1         : std_logic_vector(15 downto 0);              
  signal clk_125                   : std_logic;
  signal clk_counter               : unsigned(4 downto 0);
  signal wait_count                : unsigned(1 downto 0);
  signal bit_counter               : unsigned(3 downto 0) := x"0";
  signal collect_bits, send_sample : std_logic            := '0';
  

begin

----------------------------------------
--divide clock down to 1.5625MHz (50e6/32)
  clk_divder : process(rst, clk50)
  begin
    if rst = '1' then
      clk_counter <= (others => '0');
    elsif rising_edge(clk50) then
      clk_counter <= clk_counter + 1;
      
    end if;
  end process;

  clk_125   <= clk_counter(4);
  SCLK      <= not clk_counter(4);
  sampleClk <= clk_counter(4);
--------------------------------------------

  collector : process(clk_125, collect_bits, send_sample, wait_count)
    variable tmp1 : std_logic_vector(15 downto 0);
  begin
    if rising_edge(clk_125) then
      if (collect_bits = '1') then                 --if sampling
        tmp1        := tmp1(14 downto 0) & data1;  --take in one bit at a time
        bit_counter <= bit_counter + 1;
        wait_count  <= "00";
        sample      <= tmp1(15 downto 0);
      elsif (send_sample = '1') then               --if sample is ready to send
        bit_counter <= "0000";
        wait_count  <= "00";
        tmp1        := x"0000";
      else
        wait_count <= wait_count+1;
      end if;
    end if;
  end process;
---------------------------------------------------- 

---------------------------------------------------
  state_update : process (clk_125, rst)  --update state
  begin
    if rising_edge(clk_125) then
      if (rst = '1') then
        current_state <= Idle;
      else
        current_state <= next_state;
      end if;
    end if;
  end process;

-----------------------------------------------------------------------------------

-----------------------------------------------------------------------------------        
  STATE_OUTPUT : process (current_state)  --outputs vasriables based on state
  begin
    if current_state = idle then
      collect_bits <= '0';
      send_sample  <= '0';
      cs           <= '1';
    elsif current_state = collect then
      collect_bits <= '1';
      send_sample  <= '0';
      cs           <= '0';
    else
      collect_bits <= '0';
      send_sample  <= '1';
      cs           <= '1';
    end if;
  end process;
  sample_ready <= send_sample;
----------------------------------------------------------------------------------

-----------------------------------------------------------------------------------    
  NEXT_STATE_OUTPUT : process (current_state, get_samples, bit_counter, wait_count)
  begin
    next_state <= current_state;
    case (current_state) is
      when idle =>
        if (get_samples = '1' and wait_count = "11") then  --wait four clock cycles 
          next_state <= collect;
        end if;
      when collect =>
        if bit_counter = "1111" then  --if all 16bits (12 real 4 zero) have been collected
          next_state <= send;
        end if;
      when send =>
        next_state <= idle;
      when others =>
        next_state <= idle;
    end case;
  end process;
-------------------------------------------------------------------------------------

end Behavioral;

